package cn.smile.business.log.impl;

import cn.smile.bean.dto.log.BanAddressDTO;
import cn.smile.bean.entity.log.BanAddress;
import cn.smile.bean.form.log.ban.BanAddressAddForm;
import cn.smile.bean.form.log.ban.BanAddressQueryForm;
import cn.smile.business.log.IBanAddressService;
import cn.smile.commons.constant.NumberConstant;
import cn.smile.commons.constant.RedisKeyConstant;
import cn.smile.commons.domain.BaseServiceImpl;
import cn.smile.commons.exceptions.BusinessException;
import cn.smile.commons.response.MyResponseCode;
import cn.smile.repository.log.BanAddressMapper;
import cn.smile.utils.BeanCopy;
import cn.smile.utils.IpUtils;
import cn.smile.utils.RedisUtil;
import com.alibaba.fastjson2.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.google.common.collect.Lists;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;
import org.springframework.util.ObjectUtils;

import jakarta.annotation.Resource;
import java.util.List;

/**
 * @author smile-jt
 */
@Slf4j
@Service
public class BanAddressServiceImpl extends BaseServiceImpl<BanAddressMapper, BanAddress> implements IBanAddressService {
    @Resource
    private RedisUtil redisUtil;

    @Override
    public void writeIpToRedis() {
        log.info("[BanAddressServiceImpl].[writeIpToRedis] ------> Write Ip Address To Redis Start");
        List<BanAddressDTO> dataList = this.queryList(new BanAddressQueryForm());
        if (CollectionUtils.isEmpty(dataList)) {
            dataList = Lists.newArrayList();
        }
        List<String> ipList = Lists.newArrayList();
        dataList.forEach(dto -> ipList.add(dto.getAddress()));
        redisUtil.set(RedisKeyConstant.BAN_ACCESS_ADDRESS, JSON.toJSONString(ipList), RedisKeyConstant.BAN_ACCESS_ADDRESS_TIMEOUT);
        log.info("[BanAddressServiceImpl].[writeIpToRedis] ------> Write Ip Address To Redis End");
    }

    @Override
    public Boolean addInfo(BanAddressAddForm form) {
        log.info("[BanAddressServiceImpl].[addInfo] ------> Add Ban Address Info Start, form = {}", JSON.toJSONString(form));
        int insertNum = NumberConstant.ZERO;
        if (!this.checkAddress(form)) {
            BanAddress entity = BeanCopy.copyBean(form, BanAddress.class);
            super.addBaseCol(entity);
            insertNum = baseMapper.insert(entity);
        }
        log.info("[BanAddressServiceImpl].[addInfo] ------> Add Ban Address Info End, insertNum = {}", insertNum);
        return insertNum > NumberConstant.ZERO;
    }

    /**
     * 检查IP地址是否存在
     *
     * @param form 请求参数
     * @return true-IP已存在, false-IP不存在
     */
    private Boolean checkAddress(BanAddressAddForm form) {
        if (!IpUtils.checkIp(form.getAddress())) {
            throw new BusinessException(MyResponseCode.SYSTEM_ERROR, "IP地址不符合“xxx.xxx.xxx.xxx“要求");
        }
        BanAddressQueryForm queryForm = new BanAddressQueryForm();
        queryForm.setAddress(form.getAddress());
        List<BanAddressDTO> dataList = this.queryList(queryForm);
        if (!CollectionUtils.isEmpty(dataList)) {
            return Boolean.TRUE;
        }
        return Boolean.FALSE;
    }

    @Override
    public List<BanAddressDTO> queryList(BanAddressQueryForm form) {
        log.info("[BanAddressServiceImpl].[queryList] ------> Query Ban Address Info Start, form = {}", JSON.toJSONString(form));
        List<BanAddress> dataList = baseMapper.selectList(this.getQueryParams(form));
        List<BanAddressDTO> result = BeanCopy.copyList(dataList, BanAddressDTO.class);
        log.info("[BanAddressServiceImpl].[queryList] ------> Query Ban Address Info End");
        return result;
    }

    /**
     * 获取查询条件
     *
     * @param form 查询参数
     */
    private LambdaQueryWrapper<BanAddress> getQueryParams(BanAddressQueryForm form) {
        LambdaQueryWrapper<BanAddress> qw = new QueryWrapper<BanAddress>().lambda().eq(BanAddress::getDeleted, Boolean.FALSE);
        if (!ObjectUtils.isEmpty(form.getAddress())) {
            qw.like(BanAddress::getAddress, form.getAddress());
        }
        return qw;
    }
}
